
// json 的使用文档
/*
Json 数据对象类的表⽰:
class Json::Value{
    Value &operator=(const Value &other); //Value重载了[]和=，因此所有的赋值和获取数据都可以通过
    Value& operator[](const std::string& key);//简单的⽅式完成 val["name"] = "xx";
    Value& operator[](const char* key);
    Value removeMember(const char* key);//移除元素
    const Value& operator[](ArrayIndex index) const; //val["score"][0]
    Value& append(const Value& value);//添加数组元素val["score"].append(88); 

    ArrayIndex size() const;//获取数组元素个数 val["score"].size();
    bool isNull(); //⽤于判断是否存在某个字段
    std::string asString() const;//转string string name = 
    val["name"].asString();
    const char* asCString() const;//转char* char *name = 
    val["name"].asCString();
    Int asInt() const;//转int int age = val["age"].asInt();
    float asFloat() const;//转float float weight = val["weight"].asFloat();
    bool asBool() const;//转 bool bool ok = val["ok"].asBool();
};

序列化接⼝
class JSON_API StreamWriter {
    virtual int write(Value const& root, std::ostream* sout) = 0;
}
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
    virtual StreamWriter* newStreamWriter() const;
}

反序列化接⼝
class JSON_API CharReader {
    virtual bool parse(char const* beginDoc, char const* endDoc, 
    Value* root, std::string* errs) = 0;
}
class JSON_API CharReaderBuilder : public CharReader::Factory {
    virtual CharReader* newCharReader() const;
}

*/


#include <iostream>
#include <cstring>
#include <string>
#include <sstream>
#include <memory>
#include <jsoncpp/json/json.h>

    //使用jsoncpp库进行多个数据对象的序列化
std::string serialize(){
    //1. 将需要进行序列化的数据，存储在Json::Value 对象中
    Json::Value root;
    root["姓名"] = "小敏";
    root["年龄"] = 20;
    // 因为成绩的话有几个学科的成绩，所以是一个数组存储。数组添加元素得用append接口的哦
    root["成绩"].append(89);  
    root["成绩"].append(89.4);
    root["成绩"].append(96);

    //2. 实例化一个StreamWriterBuilder工厂类对象
    // cpp设计模式里面的工厂模式, 实例化一个工厂swb
    Json::StreamWriterBuilder swb;

    //3. 通过StreamWriterBuilder工厂类对象生产一个StreamWriter对象
    Json::StreamWriter *sw = swb.newStreamWriter();

    //4. 使用StreamWriter对象，对Json::Value中存储的数据进行序列化
    std::stringstream ss;
    int ret = sw->write(root, &ss);
    // 通过看 write 的使用手册可以看出来 --> write 函数的返回值目前都是返回0的(几乎不会有问题，有问题也是 ss 的问题)
    if(ret != 0){
        std::cout << "json serialize failed!!!\n";
        return "";
    }
    std::cout << ss.str() << std::endl;
    delete sw;   // new 出来的对象得记得 delete 的哦

    return ss.str();
}

//使用jsoncpp库进行多个数据对象的反序列化
void unserialize(const std::string& str){
    //1. 实例化一个CharReaderBuilder工厂类对象
    Json::CharReaderBuilder cb;

    //2. 使用CharReaderBuilder工厂类生产一个CharReader对象
    Json::CharReader *cr = cb.newCharReader();

    //3. 定义一个Json::Value对象存储解析后的数据
    Json::Value root;
    std::string err;

    //4. 使用CharReader对象进行json格式字符串str的反序列化
    bool ret = cr->parse(str.c_str(), str.c_str() + str.size(), &root, &err);
    if(ret == false){
        std::cout << "json unserialize failed: " << err << std::endl;
        return;
    }

    //5. 逐个元素去访问Json::Value中的数据
    std::cout << "姓名 " << root["姓名"].asString() << std::endl;
    std::cout << "年龄 " << root["年龄"].asInt() << std::endl;
    int cnt = root["成绩"].size();
    for(int i = 0; i < cnt; i++)
        std::cout << "成绩 " << root["成绩"][i].asFloat() << std::endl;

    delete cr;  // new 出来的对象得记得 delete 的哦
}

int main(void){
    std::string str = serialize();

    unserialize(str);

    return 0;
}

